package com.zpy.SmartChargeStation.netty.server.websocket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.CommandLineRunner;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * description: Netty 服务端固定模板
 */

@Component
@Slf4j
public class WebSocketServ implements CommandLineRunner {

    private NioEventLoopGroup boss;
    private NioEventLoopGroup worker;

    private Channel channel;

    @Value("${Netty.server.port}")
    private int port;

    /**
     * description: Netty启动
     */
    public void start() {

        //处理网络请求
        boss = new NioEventLoopGroup();
        //处理网络IO
        worker = new NioEventLoopGroup();

        ServerBootstrap bootstra = new ServerBootstrap();
        bootstra
                //配置NioEventLoop
                .group(boss,worker)
                //配置Channel
                .channel(NioServerSocketChannel.class)
                //将ChannelHandler添加上ChannelPipeline
                .childHandler(new ImoocChannelInit());

        //绑定服务器直到绑定成功为止
        ChannelFuture future = null;
        try {
            future = bootstra.bind(port).sync();
            log.info(">>>>>Netty (WebSocket) 开始监听端口: {}<<<<<", port);

            if(future.isSuccess()) {
                log.info(">>>>>Netty (WebSocket) 服务器启动成功");
            }

            //服务器等待通道关闭，因为使用sync()，所以关闭操作也会被阻塞
            future.channel().closeFuture().sync();

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {

            //优雅关闭组件

            if(boss != null)
                boss.shutdownGracefully();
            if(worker != null)
                worker.shutdownGracefully();
            if(channel != null)
                channel.closeFuture();

        }


    }


    /**
     * description: Netty 关闭
     */
    @PreDestroy
    public void destory() {

        try {
            if(boss != null)
                boss.shutdownGracefully().sync();
            if(worker != null)
                worker.shutdownGracefully().sync();
            if(channel != null)
                channel.closeFuture().syncUninterruptibly();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    @Async
    @Override
    public void run(String... args) throws Exception {
        start();
    }
}
